package com.gateway.bootstrap.convert;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.gateway.common.dto.ConditionData;
import com.gateway.common.dto.PluginData;
import com.gateway.common.dto.RuleData;
import com.gateway.common.dto.SelectorData;
import com.gateway.common.dto.sync.PluginSyncData;
import com.gateway.common.dto.sync.RuleSyncData;
import com.gateway.common.dto.sync.SelectorSyncData;
import com.gateway.common.enums.DeletedEnum;
import com.gateway.plugin.base.convert.PluginDataConvert;
import com.gateway.repository.bean.GatewayPlugin;
import com.gateway.repository.bean.GatewayPluginRule;
import com.gateway.repository.bean.GatewayPluginSelector;
import com.gateway.repository.bean.RuleCondition;
import com.gateway.repository.bean.SelectorCondition;
import com.gateway.repository.service.GatewayPluginRuleService;
import com.gateway.repository.service.GatewayPluginSelectorService;
import com.gateway.repository.service.GatewayPluginService;
import com.gateway.repository.service.RuleConditionService;
import com.gateway.repository.service.SelectorConditionService;
import jakarta.annotation.Resource;
import org.apache.ibatis.annotations.Delete;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @program: api-gateway
 * @description:
 * @author: YuKai Fan
 * @create: 2025/2/6 10:32
 **/
@Component
public class PluginDataConvertFunction implements PluginDataConvert {
    private static final Logger log = LoggerFactory.getLogger(PluginDataConvertFunction.class);
    @Resource
    private GatewayPluginService gatewayPluginService;
    @Resource
    private RuleConditionService ruleConditionService;
    @Resource
    private SelectorConditionService selectorConditionService;
    @Resource
    private GatewayPluginRuleService gatewayPluginRuleService;
    @Resource
    private GatewayPluginSelectorService gatewayPluginSelectorService;



    @Override
    public PluginData apply(PluginSyncData pluginSyncData) {
        GatewayPlugin gatewayPlugin = gatewayPluginService.getOne(
                new QueryWrapper<GatewayPlugin>().lambda()
                        .eq(GatewayPlugin::getEnv, pluginSyncData.getEnv())
                        .eq(GatewayPlugin::getId, pluginSyncData.getPluginId())
                        .eq(GatewayPlugin::getName, pluginSyncData.getPluginName())
                        .eq(GatewayPlugin::getDeleted, DeletedEnum.NO.value)
        );
        if (Objects.isNull(gatewayPlugin)) {
            log.error("PluginDataConvertFunction query Gateway Plugin empty, syncData={}", pluginSyncData);
            return null;
        }
        return convert(gatewayPlugin);
    }

    @Override
    public SelectorData apply(SelectorSyncData selectorSyncData) {
        GatewayPluginSelector gatewayPluginSelector = gatewayPluginSelectorService.getOne(
                new QueryWrapper<GatewayPluginSelector>().lambda()
                        .eq(GatewayPluginSelector::getEnv, selectorSyncData.getEnv())
                        .eq(GatewayPluginSelector::getId, selectorSyncData.getSelectId())
                        .eq(GatewayPluginSelector::getDeleted, DeletedEnum.NO.value)
        );
        if (Objects.isNull(gatewayPluginSelector)) {
            log.error("PluginDataConvertFunction query Gateway Selector empty, syncData={}", selectorSyncData);
            return null;
        }
        List<SelectorCondition> conditionList = selectorConditionService.list(
                new QueryWrapper<SelectorCondition>().lambda()
                        .eq(SelectorCondition::getSelectorId, gatewayPluginSelector.getId())
                        .eq(SelectorCondition::getDeleted, DeletedEnum.NO.value)
        );
        return convert(gatewayPluginSelector, conditionList);
    }

    @Override
    public RuleData apply(RuleSyncData ruleSyncData) {
        GatewayPluginRule gatewayPluginRule = gatewayPluginRuleService.getOne(
                new QueryWrapper<GatewayPluginRule>().lambda()
                        .eq(GatewayPluginRule::getEnv, ruleSyncData.getEnv())
                        .eq(GatewayPluginRule::getId, ruleSyncData.getRuleId())
                        .eq(GatewayPluginRule::getDeleted, DeletedEnum.NO.value)
        );
        if (Objects.isNull(gatewayPluginRule)) {
            log.error("PluginDataConvertFunction query Gateway Rule empty, syncData={}", ruleSyncData);
            return null;
        }
        List<RuleCondition> conditionList = ruleConditionService.list(
                new QueryWrapper<RuleCondition>().lambda()
                        .eq(RuleCondition::getRuleId, gatewayPluginRule.getId())
                        .eq(RuleCondition::getDeleted, DeletedEnum.NO.value)
        );
        return convert(gatewayPluginRule, conditionList);
    }

    /**
     * 数据转换
     * @param gatewayPlugin
     * @return
     */
    public static PluginData convert(GatewayPlugin gatewayPlugin) {
        PluginData pluginData = new PluginData();
        pluginData.setId(String.valueOf(gatewayPlugin.getId()));
        pluginData.setName(gatewayPlugin.getName());
        pluginData.setConfig(gatewayPlugin.getConfig());
        pluginData.setSort(gatewayPlugin.getSort());
        pluginData.setEnabled(gatewayPlugin.getEnabled());
        pluginData.setNoSelectorButExecute(gatewayPlugin.getNoSelectorButExecute());
        return pluginData;
    }

    public static SelectorData convert(GatewayPluginSelector selector, List<SelectorCondition> conditionList) {
        SelectorData selectorData = new SelectorData();
        selectorData.setId(String.valueOf(selector.getId()));
        selectorData.setPluginId(String.valueOf(selector.getPluginId()));
        selectorData.setContinued(selector.getContinued());
        selectorData.setEnabled(selector.getEnabled());
        selectorData.setLogged(selector.getLoged());
        selectorData.setHandle(selector.getHandle());
        selectorData.setMatchMode(selector.getMatchMode());
        selectorData.setName(selector.getName());
        selectorData.setPluginName(selector.getPluginName());
        selectorData.setSort(selector.getSort());
        selectorData.setType(selector.getType());
        selectorData.setConditionList(conditionList.stream().map(condition -> {
            ConditionData conditionData = new ConditionData();
            conditionData.setOperator(condition.getOperator());
            conditionData.setParamName(condition.getParamName());
            conditionData.setParamValue(condition.getParamValue());
            conditionData.setParamType(condition.getParamType());
            return conditionData;
        }).collect(Collectors.toList()));
        return selectorData;
    }

    public static RuleData convert(GatewayPluginRule rule, List<RuleCondition> conditionList) {
        RuleData ruleData = new RuleData();
        ruleData.setId(String.valueOf(rule.getId()));
        ruleData.setSelectorId(String.valueOf(rule.getSelectorId()));
        ruleData.setEnabled(rule.getEnabled());
        ruleData.setHandle(rule.getHandle());
        ruleData.setLoged(rule.getLoged());
        ruleData.setMatchMode(rule.getMatchMode());
        ruleData.setName(rule.getName());
        ruleData.setPluginName(rule.getPluginName());
        ruleData.setSort(rule.getSort());
        ruleData.setConditionDataList(conditionList.stream().map(condition -> {
            ConditionData conditionData = new ConditionData();
            conditionData.setOperator(condition.getOperator());
            conditionData.setParamName(condition.getParamName());
            conditionData.setParamValue(condition.getParamValue());
            conditionData.setParamType(condition.getParamType());
            return conditionData;
        }).collect(Collectors.toList()));
        return ruleData;
    }

}
